//
//  CheckBoxMenu.swift
//  liveimoocs
//
//  Created by wenkai on 2017/11/30.
//  Copyright © 2017年 wenkai. All rights reserved.
//

import UIKit
import CoreGraphics
import QuartzCore

private let kCellDefaultHeight: CGFloat = 30

public typealias actionClickBlock = ((_ title: String?, _ index: Int?) -> ())

open class WKCheckBoxMenu: UIView {
    //可定制参数
    public var listBackGroundColor: UIColor = UIColor.groupTableViewBackground
    public var font: UIFont = UIFont.systemFont(ofSize: 14)
    public var autoCloseWhenSelected: Bool = true
    public var textColor:UIColor = UIColor.black
    public var indicatorColor:UIColor = UIColor.black
    public var cellClickedBlock: actionClickBlock?
    
    public var rowHeight: CGFloat = kCellDefaultHeight {
        didSet {
            self.setNeedsDisplay()
        }
    }
    public var datas: [String]? {
        didSet{
            self.listTableView.reloadData()
        }
    }
    public var boxBackGroundColor:UIColor = UIColor.white {
        willSet{
            self.headerBtn.backgroundColor = newValue
        }
    }
    
    
    private var headerSelected: Bool = false
    private var shapeLayer: CAShapeLayer?
    
    lazy var headerBtn: UIButton = {
        let btn = UIButton(frame: CGRect(x: 0, y: 0, width: listTableView.frame.size.width, height: self.rowHeight))
        btn.titleLabel?.font = self.font
        btn.setTitle(self.datas?[0], for: .normal)
        btn.setTitleColor(self.textColor, for: .normal)
        btn.backgroundColor = self.boxBackGroundColor
        btn.titleEdgeInsets = UIEdgeInsetsMake(0, 15, 0, 0)
        btn.contentHorizontalAlignment = .left
        btn.addTarget(self, action: #selector(headerBtnAction), for: .touchUpInside)
        let position = CGPoint(x: btn.frame.size.width-10, y: btn.frame.size.height/2)
        let shapeLayer = createIndicatorWihtColor(color: self.indicatorColor, position: position)
        self.shapeLayer = shapeLayer
        btn.layer.addSublayer(shapeLayer)
        return btn
    }()
    //内部实现对外不开放
    lazy var listTableView:UITableView = {
        let tableView = UITableView(frame: CGRect.zero, style: UITableViewStyle.grouped)
        tableView.separatorStyle = .none
        tableView.bounces = false
        tableView.delegate = self
        tableView.dataSource = self
        tableView.estimatedRowHeight = 0.0
        tableView.estimatedSectionFooterHeight = 0.0
        tableView.estimatedSectionHeaderHeight = 0.0
        tableView.frame = CGRect(x: 0, y: 0, width: self.frame.size.height, height: kCellDefaultHeight)
        tableView.register(UITableViewCell.classForCoder(), forCellReuseIdentifier: "DropMenuCellIdentifier")
        
        if #available(iOS 11.0, *) {
            tableView.contentInsetAdjustmentBehavior = .never;
        }
        return tableView
    }()
    
    override public init(frame: CGRect) {
        super.init(frame: frame)
        makeUpUI()
    }
    
    convenience public init(titles: [String]?) {
        self.init(frame: CGRect.zero)
        self.datas = titles
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func makeUpUI() {
        self.layer.borderWidth = 0.5
        self.layer.borderColor = indicatorColor.cgColor
        self.layer.masksToBounds = true
        
        self.addSubview(listTableView)
    }
    func closeMenu() {
        if self.headerSelected {
            self.headerBtnAction()
        }
    }
    func createIndicatorWihtColor(color: UIColor, position: CGPoint) -> CAShapeLayer {
        let layer = CAShapeLayer()
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: 8, y: 0))
        path.addLine(to: CGPoint(x: 4, y:5))
        path.close()
        layer.path = path.cgPath
        layer.lineWidth = 1
        layer.fillColor = color.cgColor
        
        var boundPath = CGPath(__byStroking: (layer.path!), transform: nil, lineWidth: 4, lineCap: .round, lineJoin: .miter, miterLimit: 4)
        layer.bounds = (boundPath?.boundingBoxOfPath)!
        
        boundPath = nil
        layer.position = position
        
        return layer
    }
    
    func animateIndicator(indicator: CAShapeLayer?, forward: Bool, complete:()->()) {
        let anim = CAKeyframeAnimation(keyPath: "transform.rotation.z")
        anim.duration = 0.25
        anim.fillMode = kCAFillModeForwards
        anim.isRemovedOnCompletion = false
        anim.values = forward ? [0,Double.pi] : [Double.pi, 0]
        if !anim.isRemovedOnCompletion {
            indicator?.add(anim, forKey: anim.keyPath)
        }
        else {
            
            indicator?.setValue(anim.values?.last, forKey: anim.keyPath!)
            indicator?.add(anim, forKey: anim.keyPath)
        }
        
        complete()
    }
    
    func cellInsertOrDelete(insert: Bool) {
        self.listTableView.beginUpdates()
        var indexPaths = [IndexPath]()
        for (index, _) in self.datas!.enumerated(){
            let indexP = IndexPath(row: index, section: 0)
            indexPaths.append(indexP)
        }
        if insert {
            self.listTableView.insertRows(at: indexPaths, with: .top)
        }
        else {
            self.listTableView.deleteRows(at: indexPaths, with: .bottom)
        }
        self.listTableView.endUpdates()
    }
    
    override open func layoutSubviews() {
        super.layoutSubviews()
        if self.headerSelected, let titles = self.datas {
            let tempHeight = CGFloat(titles.count) * self.rowHeight + self.rowHeight
            self.frame.size.height = tempHeight > 150 ? 150 : tempHeight
        }
        else {
            self.frame.size.height = self.rowHeight
        }
        self.listTableView.frame = self.bounds
    }

}

extension WKCheckBoxMenu {
    @objc func headerBtnAction() {
        self.headerSelected = !self.headerSelected
        self.setNeedsLayout()
        animateIndicator(indicator: self.shapeLayer, forward: self.headerSelected) {
            [unowned self] in
            self.cellInsertOrDelete(insert: self.headerSelected)
        }
    }
}

extension WKCheckBoxMenu: UITableViewDelegate, UITableViewDataSource {
    
    public func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if  self.headerSelected, let title = self.datas {
            return title.count
        }
        return 0
    }
    
    public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return self.rowHeight == 0 ? kCellDefaultHeight : self.rowHeight
    }
    
    public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return self.rowHeight == 0 ? kCellDefaultHeight : self.rowHeight
    }
    
    public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 0.001
    }
    
    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "DropMenuCellIdentifier",
                                                                  for: indexPath)
        cell.textLabel?.text = self.datas?[indexPath.row]
        cell.textLabel?.font = self.font
        cell.textLabel?.textColor = self.textColor
        cell.contentView.backgroundColor = self.listBackGroundColor
        cell.textLabel?.backgroundColor = self.listBackGroundColor
        return cell
    }
    
    public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return headerBtn
    }
    
    public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
         self.headerBtn .setTitle(self.datas?[indexPath.row], for: .normal)
        
        if let block = self.cellClickedBlock {
            block(self.datas?[indexPath.row], indexPath.row)
        }
        
        if self.autoCloseWhenSelected {
            self.closeMenu()
        }
    }
    
}
